package com.hydra.modulecenter;

import android.app.Application;
import android.util.Log;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import com.hydra.framework.event.fw.FWEvent;
import com.hydra.framework.event.fw.FWEventActionKey;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Created by hasee on 2017/7/22.
 *
 */
@SuppressWarnings("unchecked")
public class ModuleCenter {

    static final String MC_LOG_TAG = "ModuleCenter";

    private static Application sApplication;

    private static Map<String, ModuleInfo> sModules = new HashMap<>();

    static {
        for(ModuleConfig moduleConfig : ModuleConfig.values()) {
            try {
                ModuleInfo moduleInfo = new ModuleInfo();

                moduleInfo.interfaceCls = (Class<? extends IModuleInterface>)
                        Class.forName(moduleConfig.interfaceClsName);
                moduleInfo.moduleCls = (Class<? extends IModuleInterface>)
                        Class.forName(moduleConfig.moduleClsName);
                moduleInfo.isPreLoad = moduleConfig.preLoad;

                sModules.put(moduleConfig.interfaceClsName, moduleInfo);
            } catch (ClassNotFoundException | NoClassDefFoundError e) {
                Log.e(MC_LOG_TAG, "init module class failed : " + moduleConfig.interfaceClsName + " error : " + e.toString());
            }
        }
    }

    @MainThread
    public static void init(Application application) {
        sApplication = application;

        initModules();
    }

    public static Application getApplication() {
        return sApplication;
    }

    private static void initModules() {
        Iterator<Entry<String, ModuleInfo>> iterator = sModules.entrySet().iterator();

        while (iterator.hasNext()) {
            ModuleInfo moduleInfo = iterator.next().getValue();

            if(moduleInfo.isPreLoad) {
                moduleInfo.initInstance();
            }
        }

        FWEvent.sendEvent(sModules, FWEventActionKey.FWAction_On_Launch_PreLoad_Module_Finished);
    }

    public static <T extends IModuleInterface> T module(@NonNull Class<T> moduleInterface) {
        ModuleInfo moduleInfo = sModules.get(moduleInterface.getName());

        if(moduleInfo == null) {
            Log.e(MC_LOG_TAG, "get Module Failed, Module " + moduleInterface.getName() + " is not in ModuleMap");
            return null;
        }

        return moduleInfo.getModuleInstance();
    }


}
